/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
#ifndef DISPLAYCANVAS_H_
#define DISPLAYCANVAS_H_

#include <vector>
#include <wx/wx.h>
#include "GLCanvas.h"
#include "MachineUnit.h"

#define CLEAR_COLOR         0.2,0.2,0.2

#define GRID_COLOR          0.0,0.5,0.0
#define GRID_LINE_WIDTH     1
#define AXIS_COLOR          0.5,0.0,0.0

#define MAP_COLOR           0.2,0.5,0.8
#define MAP_LINE_WIDTH      2

#define SCALE_MAX           1000
#define SCALE_MIN           10

namespace MaCIGUI
{

struct TMapLine
{
  float x1, x2, y1, y2;
};

class CDisplayCanvas : public CGLCanvas
{
  DECLARE_EVENT_TABLE()
  public:

    CDisplayCanvas(wxWindow *ParentWindow);


    void SetGrid(bool grid, float size);

    void SetMode(int mode);

    void SetMap(const char *fileName);

    void SetTerrain(const char *fileName);

    void SetSelectedUnit(CMachineUnit *unit);
    void AddMachineUnit(CMachineUnit *unit);
    void RemoveMachineUnit(CMachineUnit *unit);

    void SetViewOrigin(float x, float y);
    /** event handlers **/
    //mouse events
    void OnMouseWheel(wxMouseEvent &e);
    void OnLeftDown(wxMouseEvent &e);
    void OnDoubleClick(wxMouseEvent &e);
    void OnMotion(wxMouseEvent &e);
    //key events
    void OnKey(wxKeyEvent &e);
    void OnKeyUp(wxKeyEvent &e);
    //other
    void OnContextMenu(wxContextMenuEvent &e);
    
    void OnKillFocus(wxFocusEvent &e);
    
    void OnPaint(wxPaintEvent &e);
    void OnSize(wxSizeEvent &e);


    static const int DRAW_MODE_3D;
    static const int DRAW_MODE_2D;
    static const int VIEW_MODE_FOLLOW;
    static const int VIEW_MODE_UNIVERSAL;

  private:
    static int attribList[3];
    
    wxGLContext GLContext;
    bool glInited;
    std::vector<CMachineUnit*> machineUnits;
    CMachineUnit* selectedUnit;

    ownMutexHandle machinesMutex;
    
    wxMenu popupMenu;

    //map params
    bool map;
    float mapZ;
    std::vector<TMapLine> mapLines;

    //terrain params
    bool terrain;
    float terrainMaxHeight, terrainMinHeight;

    //grid params
    bool grid;
    float gridZ;
    float gridSize;

    //view params
    int renderMode; //render mode, 2d/3d
    int viewMode; //viewing mode, universal/follow unit
    int scale; //pixels per meter
    float viewLeft, viewRight, viewTop, viewBottom; //view bounds
    float viewOriginX, viewOriginY; //view location

    //display list identifiers
    GLuint dispList_heightMap2D; //terrain in 2d mode
    GLuint dispList_heightMap3D; //terrain in 3d mode
    GLuint dispList_model; //extra models in 3d mode

    //mouse pointer postion etc
    float pointerX, pointerY; //on map
    float pointerRelX, pointerRelY, pointerRelDist, pointerRelAngle; //relative to robot
    int mouseClickX, mouseClickY; //location of last click

    void initGL();

    void setView();

    void draw();

    void drawUnits();
    void drawGrid();
    void drawMap();
    void drawTerrain();

    //coordinate conversions in 2d
    void metersToPixels(float mx, float my, int *px, int *py);
    void pixelsToMeters(int px, int py, float *mx, float *my);
};

}

#endif /*DISPLAYCANVAS_H_*/
